Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add internal column to service template for transformation plan #17748

Merged

Conversation

hsong-rh
Copy link
Contributor

@hsong-rh hsong-rh commented Jul 23, 2018

Add internal flag to limit the access scope for transformation plan.

https://bugzilla.redhat.com/show_bug.cgi?id=1594408

Schema PR to migrate away from reserves table: ManageIQ/manageiq-schema#238.

@hsong-rh
Copy link
Contributor Author

@bzwei @gmcculloug Please review.

@gmcculloug
Copy link
Member

@bdunne @Fryguy Can you give this a quick review?

Note in the description that the first commit is for Gaprindashvili so it uses the ReservedMixin. Also, tests are failing because of the schema PR dependency.

@@ -74,6 +77,7 @@ class ServiceTemplate < ApplicationRecord
scope :without_service_template_catalog_id, -> { where(:service_template_catalog_id => nil) }
scope :with_existent_service_template_catalog_id, -> { where.not(:service_template_catalog_id => nil) }
scope :displayed, -> { where(:display => true) }
scope :public_service_template, -> { where(:internal => true) }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this work? I don't think you can use a where like this to query on a reserved attribute.

I tried it on another model and got:

NoMethodError: undefined method `eq' for nil:NilClass
	from /home/bdunne/.gem/ruby/2.4.3/gems/activerecord-5.0.7/lib/active_record/relation/predicate_builder/basic_object_handler.rb:9:in `call'
	from /home/bdunne/.gem/ruby/2.4.3/gems/activerecord-5.0.7/lib/active_record/relation/predicate_builder.rb:76:in `build'
	from /home/bdunne/.gem/ruby/2.4.3/gems/activerecord-5.0.7/lib/active_record/relation/predicate_builder.rb:46:in `expand'
	from /home/bdunne/.gem/ruby/2.4.3/gems/activerecord-5.0.7/lib/active_record/relation/predicate_builder.rb:90:in `block in expand_from_hash'
	from /home/bdunne/.gem/ruby/2.4.3/gems/activerecord-5.0.7/lib/active_record/relation/predicate_builder.rb:86:in `each'
	from /home/bdunne/.gem/ruby/2.4.3/gems/activerecord-5.0.7/lib/active_record/relation/predicate_builder.rb:86:in `flat_map'
	from /home/bdunne/.gem/ruby/2.4.3/gems/activerecord-5.0.7/lib/active_record/relation/predicate_builder.rb:86:in `expand_from_hash'
	from /home/bdunne/.gem/ruby/2.4.3/gems/activerecord-5.0.7/lib/active_record/relation/predicate_builder.rb:31:in `build_from_hash'
	from /home/bdunne/.gem/ruby/2.4.3/gems/activerecord-5.0.7/lib/active_record/relation/where_clause_factory.rb:22:in `build'
	from /home/bdunne/.gem/ruby/2.4.3/gems/activerecord-5.0.7/lib/active_record/relation/query_methods.rb:632:in `where!'
	from /home/bdunne/.gem/ruby/2.4.3/gems/activerecord-5.0.7/lib/active_record/relation/query_methods.rb:625:in `where'
	from /home/bdunne/.gem/ruby/2.4.3/gems/activerecord-5.0.7/lib/active_record/querying.rb:10:in `where'
	from (irb):2
	from /home/bdunne/.gem/ruby/2.4.3/gems/railties-5.0.7/lib/rails/commands/console.rb:65:in `start'
	from /home/bdunne/.gem/ruby/2.4.3/gems/railties-5.0.7/lib/rails/commands/console_helper.rb:9:in `start'
	from /home/bdunne/.gem/ruby/2.4.3/gems/railties-5.0.7/lib/rails/commands/commands_tasks.rb:78:in `console'
	from /home/bdunne/.gem/ruby/2.4.3/gems/railties-5.0.7/lib/rails/commands/commands_tasks.rb:49:in `run_command!'
	from /home/bdunne/.gem/ruby/2.4.3/gems/railties-5.0.7/lib/rails/commands.rb:18:in `<top (required)>'
	from bin/rails:4:in `require'
	from bin/rails:4:in `<main>'

@@ -75,6 +78,10 @@ class ServiceTemplate < ApplicationRecord
scope :with_existent_service_template_catalog_id, -> { where.not(:service_template_catalog_id => nil) }
scope :displayed, -> { where(:display => true) }

def self.public_service_templates
ServiceTemplate.all - ServiceTemplate.joins(:reserved_rec).where(:reserves=> {:reserved => {:internal => true}.to_yaml}).to_a
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. This should return a scope if possible
  2. That where clause is wrong, because there could be other things in reserves if we need to add them.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, please add a spec

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Fryguy what is the way to write the where clause? We tested but cannot make reserved field deserialized in this query.

Copy link
Contributor

@bzwei bzwei Jul 24, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we query like ServiceTemplate.includes(:reserved_rec).select { |s| !s.internal }?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Fryguy Changed back to scope based on above query.

@bdunne
Copy link
Member

bdunne commented Jul 24, 2018

Injecting a ServiceTemplateInternal subclass is looking better and better... What do you think @gmcculloug?

@Fryguy
Copy link
Member

Fryguy commented Jul 24, 2018

👎 for subclass...it conflates a property of potentially any service template with the type of a service template.

@@ -74,6 +77,7 @@ class ServiceTemplate < ApplicationRecord
scope :without_service_template_catalog_id, -> { where(:service_template_catalog_id => nil) }
scope :with_existent_service_template_catalog_id, -> { where.not(:service_template_catalog_id => nil) }
scope :displayed, -> { where(:display => true) }
scope :public_service_templates, -> { includes(:reserved_rec).select { |s| s.internal.nil? }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hsong-rh You are missing the closing bracket on the scope.

@@ -1,4 +1,7 @@
class ServiceTemplate < ApplicationRecord
include ReservedMixin
reserve_attribute :internal, :boolean
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These lines should be moved down by the other include statements around line 38.

@@ -7,6 +7,8 @@ def request_type
"transformation_plan"
end

default_value_for :internal, true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We would also want a default_value_for :internal, false at the base class.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we really want such a default_value? Without default we don't need to insert a record in the reserved table.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer this upstream once we have the real column, so it is fine to ignore while we are working on the reserves table commits.

@@ -74,6 +77,7 @@ class ServiceTemplate < ApplicationRecord
scope :without_service_template_catalog_id, -> { where(:service_template_catalog_id => nil) }
scope :with_existent_service_template_catalog_id, -> { where.not(:service_template_catalog_id => nil) }
scope :displayed, -> { where(:display => true) }
scope :public_service_templates, -> { includes(:reserved_rec).select { |s| s.internal.nil? } }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the condition be !s.internal to handle both nil and false values.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This returns an array, but we want a true scope. The best I can come up is

where.not(:id => ServiceTemplate.includes(:reserved_rec).joins(:reserved_rec).select { |s| s.internal == true }.collect(&:id))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bzwei 👍

@hsong-rh hsong-rh force-pushed the add_internal_to_service_template branch 3 times, most recently from 42d0556 to da7a48d Compare July 25, 2018 13:28
Copy link
Member

@gmcculloug gmcculloug left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bdunne @Fryguy Any further comments?

Note, the existing scope is intended for gaprindashvili and will be changed upstream once we have the new internal column available.

@gmcculloug
Copy link
Member

@bdunne @Fryguy bump

st1 = FactoryGirl.create(:service_template_transformation_plan)
st2 = FactoryGirl.create(:service_template)

expect(st1.internal).to be_truthy
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer internal? since it's a boolean attribute

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On second thought... Do you need to test this? It's just testing default_value_for, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, they are testing the default value, to make sure if it is set correctly. internal is column name.


expect(st1.internal).to be_truthy
expect(st2.internal).to be_falsey
expect(ServiceTemplate.public_service_templates.count).to eq(1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two expectations can be merged into:

expect(ServiceTemplate.public_service_templates).to match_array([st2])

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed.

@hsong-rh hsong-rh force-pushed the add_internal_to_service_template branch from da7a48d to d22be20 Compare July 30, 2018 14:02
Copy link
Member

@kbrock kbrock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

filtering on columns that are serialized in reserves#reserved will always bring back all records. (sure wish it were an hstore or jsonb column)

@@ -74,6 +76,7 @@ class ServiceTemplate < ApplicationRecord
scope :without_service_template_catalog_id, -> { where(:service_template_catalog_id => nil) }
scope :with_existent_service_template_catalog_id, -> { where.not(:service_template_catalog_id => nil) }
scope :displayed, -> { where(:display => true) }
scope :public_service_templates, -> { where.not(:id => ServiceTemplate.includes(:reserved_rec).joins(:reserved_rec).select { |s| s.internal == true }.collect(&:id)) }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure if the joins is necessary

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kbrock What if we query the Reserve first?

where.not(:id => Reserved.where(:resource_type => "ServiceTemplate").all.collect { |r| r.resource_id if r[:internal] == true }.compact)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kbrock Without join, ServiceTemplate.includes(:reserved_rec).select { |s| s.internal == true }.collect(&:id) give us same result.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hsong-rh Remember we need to retain this as a scope so users can chain other scopes onto the resulting object.

Copy link
Contributor Author

@hsong-rh hsong-rh Jul 30, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bdunne This works: where.not(:id => Reserve.where(:resource_type => "ServiceTemplate").all.collect { |r| r.resource_id if r.reserved[:internal] == true }.compact)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gmcculloug yes, they return as scope.

@@ -74,6 +76,7 @@ class ServiceTemplate < ApplicationRecord
scope :without_service_template_catalog_id, -> { where(:service_template_catalog_id => nil) }
scope :with_existent_service_template_catalog_id, -> { where.not(:service_template_catalog_id => nil) }
scope :displayed, -> { where(:display => true) }
scope :public_service_templates, -> { where.not(:id => Reserve.where(:resource_type => "ServiceTemplate").all.collect { |r| r.resource_id if r.reserved[:internal] == true }.compact) }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you don't need .all, or even simpler

where.not(:id => Reserve.where(:resource_type => "ServiceTemplate").collect { |r| r.reserved[:internal] && r.resource_id }.compact

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bzwei Changed.

@hsong-rh hsong-rh force-pushed the add_internal_to_service_template branch from 61ec522 to ee21a01 Compare July 30, 2018 18:50
@gmcculloug
Copy link
Member

@Fryguy @bdunne @kbrock Any chance we can get this merged today?

@kbrock I hear your concern, we'll be migrating away from this upstream. The good news is this is against service_templates which is likely to be in the 100s of instances and not services.

@bdunne
Copy link
Member

bdunne commented Jul 30, 2018

Oh, good catch on the r.reserved[:internal], and not needing the == true. Any reason that you used && rather than if?

@bzwei
Copy link
Contributor

bzwei commented Jul 30, 2018

@bdunne The line is too long. Just to make it shorter.

@bdunne
Copy link
Member

bdunne commented Jul 30, 2018

Too long for what?

@bzwei
Copy link
Contributor

bzwei commented Jul 30, 2018

Previously the line for the scope is very long. I thought we can make it shorter and proposed to use &&. It is an issue of coding style preference. Feel free to choose the way you want to code.

@gmcculloug
Copy link
Member

@bdunne Do you have a preference? I feel like this PR is really close now and would like to see if we can get it to the finish line. 🏁

@bdunne
Copy link
Member

bdunne commented Jul 31, 2018

I thought if reads better, but it doesn't really matter

@hsong-rh hsong-rh force-pushed the add_internal_to_service_template branch from ee21a01 to 54daf2a Compare July 31, 2018 15:32
@hsong-rh
Copy link
Contributor Author

@bdunne Changed as you suggested. Thanks,

@hsong-rh hsong-rh force-pushed the add_internal_to_service_template branch from 54daf2a to f333539 Compare July 31, 2018 15:40
@miq-bot
Copy link
Member

miq-bot commented Jul 31, 2018

Checked commit hsong-rh@f333539 with ruby 2.3.3, rubocop 0.52.1, haml-lint 0.20.0, and yamllint 1.10.0
3 files checked, 0 offenses detected
Everything looks fine. 🍪

@gmcculloug gmcculloug merged commit 2a66cb5 into ManageIQ:master Jul 31, 2018
@hsong-rh hsong-rh deleted the add_internal_to_service_template branch July 31, 2018 18:12
@gmcculloug gmcculloug added this to the Sprint 92 Ending Aug 13, 2018 milestone Jul 31, 2018
simaishi pushed a commit that referenced this pull request Aug 1, 2018
Add internal column to service template for transformation plan
(cherry picked from commit 2a66cb5)

https://bugzilla.redhat.com/show_bug.cgi?id=1610729
@simaishi
Copy link
Contributor

simaishi commented Aug 1, 2018

Gaprindashvili backport details:

$ git log -1
commit 685c571bef061200b7a26b8aa3b4f3577014733e
Author: Greg McCullough <gmccullo@redhat.com>
Date:   Tue Jul 31 12:07:50 2018 -0400

    Merge pull request #17748 from hsong-rh/add_internal_to_service_template
    
    Add internal column to service template for transformation plan
    (cherry picked from commit 2a66cb59e26816c7296896620b5b7731b350943d)
    
    https://bugzilla.redhat.com/show_bug.cgi?id=1610729

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants